package mainControlsTest;

import junit.framework.TestCase;
import mainControls.Scheduler;
import entities.Course;
import entities.Room;
import entities.Section;
import entities.Staff;
import entities.AcdcProgram;
public class SchedulerTest extends TestCase {
	Scheduler scheduler;

	public void setUp() {
		scheduler = new Scheduler();
	}

	public void tearDown() {
		Room.clear();
		Section.clear();
		Staff.clear();
		Course.clear();
		AcdcProgram.clear();
	}
	
	public void test_CoreCourses()
	{
		new Section("CS1_C01", 40, 2, "Staff01");
		new Section("CS2_C01", 40, 2, "Staff02");
		
		String[] strPrograms={"BScCS"};
		new AcdcProgram("BScCS");
		Course course1 = new Course("CS1", strPrograms);
		course1.addLecture("CS1_C01");
		Course course2 = new Course("CS2", strPrograms);
		course2.addLecture("CS2_C01");
		
		Staff staff01 = new Staff("Staff01");
		staff01.addNewSection("CS1_C01");
		Staff staff02 = new Staff("Staff02");
		staff02.addNewSection("CS2_C01");
		
		new Room("Room1", 40);
		new Room("Room2", 40);
		
		scheduler.generateSchedule();
		
		// CS1_C01
		Section section1 = Section.getSectionById("CS1_C01");
		assertEquals("Mon 11:30", section1.getSectionStartTime().toString());
		assertEquals("Room1", section1.getSectionRoomId());
		// CS2_C01
		Section section2 = Section.getSectionById("CS2_C01");
		assertEquals("Tue 11:30", section2.getSectionStartTime().toString());
		assertEquals("Room1", section2.getSectionRoomId());
	}

	// Test case 1: one course with two lectures and two tutorials
	public void test_OneCourseWithTwoLecturesAndTwoTutorials() {
		new Section("CS1001_C01", 40, 2, "Staff01");
		new Section("CS1001_C02", 40, 2, "Staff02");
		new Section("CS1001_T01", 40, 2, "Staff03");
		new Section("CS1001_T02", 40, 2, "Staff04");

		Course course1 = new Course("CS1001", new String[0]);
		course1.addLecture("CS1001_C01");
		course1.addLecture("CS1001_C02");
		course1.addTutorial("CS1001_T01");
		course1.addTutorial("CS1001_T02");

		Staff staff01 = new Staff("Staff01");
		staff01.addNewSection("CS1001_C01");
		Staff staff02 = new Staff("Staff02");
		staff02.addNewSection("CS1001_C02");
		Staff staff03 = new Staff("Staff03");
		staff03.addNewSection("CS1001_T01");
		Staff staff04 = new Staff("Staff04");
		staff04.addNewSection("CS1001_T02");

		new Room("Room1", 40);
		new Room("Room2", 40);

		scheduler.generateSchedule();

		// CS1001_C01
		Section section1 = Section.getSectionById("CS1001_C01");
		assertEquals("Mon 11:30", section1.getSectionStartTime().toString());
		assertEquals("Room1", section1.getSectionRoomId());

		// CS1002_C01
		Section section2 = Section.getSectionById("CS1001_C02");
		assertEquals("Tue 11:30", section2.getSectionStartTime().toString());
		assertEquals("Room1", section2.getSectionRoomId());

		// CS1002_T01
		Section section3 = Section.getSectionById("CS1001_T01");
		assertEquals("Wed 11:30", section3.getSectionStartTime().toString());
		assertEquals("Room1", section3.getSectionRoomId());

		// CS1002_T02
		Section section4 = Section.getSectionById("CS1001_T02");
		assertEquals("Wed 11:30", section4.getSectionStartTime().toString());
		assertEquals("Room2", section4.getSectionRoomId());
	}

	// Test case 2: only one room
	public void test_onlyOneRoom() {
		// add sections
		new Section("CS1003_C01", 40, 2, "Staff01");
		new Section("CS1004_C01", 50, 2, "Staff02");

		// add courses
		Course course1 = new Course("CS1003", new String[0]);
		course1.addLecture("CS1003_C01");
		Course course2 = new Course("CS1004", new String[0]);
		course2.addLecture("CS1004_C01");

		// add staffs
		Staff staff01 = new Staff("Staff01");
		staff01.addNewSection("CS1003_C01");
		Staff staff02 = new Staff("Staff02");
		staff02.addNewSection("CS1004_C01");

		// add rooms
		new Room("Room1", 50);

		scheduler.generateSchedule();

		// CS1001_C01
		Section section1 = Section.getSectionById("CS1003_C01");
		assertEquals("Mon 11:30", section1.getSectionStartTime().toString());
		assertEquals("Room1", section1.getSectionRoomId());

		// CS1002_C01
		Section section2 = Section.getSectionById("CS1004_C01");
		assertEquals("Tue 11:30", section2.getSectionStartTime().toString());
		assertEquals("Room1", section2.getSectionRoomId());
	}

	// Test case 3: only one staff
	public void test_onlyOneStaff() {
		// add sections
		new Section("CS1005_C01", 40, 2, "Staff01");
		new Section("CS1006_C01", 50, 2, "Staff01");

		// add courses
		Course course1 = new Course("CS1005", new String[0]);
		course1.addLecture("CS1005_C01");
		Course course2 = new Course("CS1006", new String[0]);
		course2.addLecture("CS1006_C01");

		// add staffs
		Staff staff01 = new Staff("Staff01");
		staff01.addNewSection("CS1005_C01");
		staff01.addNewSection("CS1006_C01");

		// add rooms
		new Room("Room1", 50);

		scheduler.generateSchedule();

		// CS1001_C01
		Section section1 = Section.getSectionById("CS1005_C01");
		assertEquals(1, section1.getSectionStartTime().getDay());
		assertEquals(11, section1.getSectionStartTime().getHour());
		assertEquals(30, section1.getSectionStartTime().getMinute());

		// CS1002_C01
		Section section2 = Section.getSectionById("CS1006_C01");
		assertEquals(2, section2.getSectionStartTime().getDay());
		assertEquals(11, section2.getSectionStartTime().getHour());
		assertEquals(30, section2.getSectionStartTime().getMinute());

		// check rooms
		assertEquals("Room1", section1.getSectionRoomId());
		assertEquals("Room1", section2.getSectionRoomId());
	}

	// Test case 4: test staff over flow
	public void test_staffOverFlow() {
		// 11:30 - 14:30, 14:30 - 17:30, 17:30 - 20:30, 8:30 - 11:30

		int nDays = 5;
		int nHours = 5;

		// add section
		for (int day = 1; day <= nDays; day++) {
			for (int hour = 1; hour <= nHours; hour++) {
				Section section = new Section("CS" + day + hour, 40, 3,
						"Staff01");
				Course course = new Course("CS" + day + hour, new String[0]);
				course.addLecture(section.getSectionId());
			}
		}
		Section sectionOverFlow = new Section("CS_overFlow_C01", 40, 3,
				"Staff01");
		Course courseOverFlow = new Course("CS_overFlow", new String[0]);
		courseOverFlow.addLecture(sectionOverFlow.getSectionId());

		// add staff
		Staff staff01 = new Staff("Staff01");
		for (int day = 1; day <= nDays; day++) {
			for (int hour = 1; hour <= nHours; hour++)
				staff01.addNewSection("CS" + day + hour);
		}
		staff01.addNewSection("CS_overFlow_C01");

		// add room
		new Room("Room1", 40);

		System.out
				.println("Please ignore the following error message. It is for testing. ");
		scheduler.generateSchedule();

		// CS_overFlow
		Section section1 = Section.getSectionById("CS_overFlow_C01");
		assertEquals(null, section1.getSectionStartTime());

		// check rooms
		assertEquals(null, section1.getSectionRoomId());
	}

	// Test case 5: no appropriate room
	public void test_noRoom() {
		// add sections
		Section section = new Section("CS_NoRoom_C01", 50, 2, "Staff01");
		Course course = new Course("CS_NoRoom", new String[0]);
		course.addLecture(section.getSectionId());

		// add staffs
		Staff staff01 = new Staff("Staff01");
		staff01.addNewSection("CS_NoRoom_C01");

		// add rooms
		new Room("Room1", 40);

		System.out
				.println("Please ignore the following error message. It is for testing. ");
		scheduler.generateSchedule();

		// CS1001_C01
		Section section1 = Section.getSectionById("CS_NoRoom_C01");
		assertEquals(null, section1.getSectionStartTime());

		// check rooms
		assertEquals(null, section1.getSectionRoomId());
	}
}
